package com.ymx.darling.generater.table;

import com.ymx.darling.datasource.defaults.PooledDataSource;
import com.ymx.darling.exception.DarlingException;
import com.ymx.darling.generater.config.GlobalConfig;
import com.ymx.darling.type.TypeHandlerRegister;

import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TableUtil {
    private final static Map<String, String> getAllTableSqlMap = new HashMap<>();
    static {
        getAllTableSqlMap.put("mysql", "SHOW TABLES");
        getAllTableSqlMap.put("oracle", "SELECT table_name FROM user_tables");
        getAllTableSqlMap.put("db2", "SELECT tabname FROM syscat.tables WHERE tabschema = CURRENT SCHEMA");
        getAllTableSqlMap.put("sqlserver", "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'");
        getAllTableSqlMap.put("postgresql","SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'");
        getAllTableSqlMap.put("dm", "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = (SELECT USER FROM DUAL)");
        getAllTableSqlMap.put("kingbase", "SELECT tablename FROM sys_tables WHERE schemaname = 'public'");
        getAllTableSqlMap.put("sqlite", "SELECT name FROM sqlite_master WHERE type='table'");
    }

    /**
     * 返回数据库中所有表的数据
     * @param globalConfig globalConfig
     * @return List
     */
    public static List<Table> getTableInfoList(GlobalConfig globalConfig) {
        try {
            PooledDataSource dataSource = new PooledDataSource();
            dataSource.setUrl(globalConfig.getUrl());
            dataSource.setDriver(globalConfig.getDriver());
            dataSource.setPassword(globalConfig.getPassword());
            dataSource.setUsername(globalConfig.getUsername());
            Connection connection = dataSource.getConnection();
            // 获取所有表的名称
            List<String> tableNameList = getTables(connection);
            // 遍历表构建Table
            List<Table> tables = new ArrayList<>();
            for (String table : tableNameList) {
                tables.add(getAllFields(connection, table));
            }
            connection.close();
            return tables;
        }catch (SQLException e) {
            throw new DarlingException("访问数据库时抛出异常异常信息"+e.getMessage());
        }
    }

    private static List<String> getTables(Connection connection) throws SQLException {
        String databaseProductName = connection.getMetaData().getDatabaseProductName().toLowerCase();
        String sql = getAllTableSqlMap.get(databaseProductName);
        if (sql == null) {
            throw new DarlingException("darling不支持数据库:"+databaseProductName);
        } else {
            Statement statement = connection.createStatement();
            ResultSet resultSet = statement.executeQuery(sql);
            List<String> tables = new ArrayList<>();
            while (resultSet.next()) {
                tables.add(resultSet.getString(1));
            }
            resultSet.close();
            statement.close();

            return tables;
        }
    }

    // 方法用于获取表中所有字段信息
    private static Table getAllFields(Connection connection, String tableName) throws SQLException {
        List<Column> columns = new ArrayList<>();
        Statement statement = connection.createStatement();
        ResultSet resultSet = statement.executeQuery("select * from " + tableName);
        ResultSetMetaData metaData = resultSet.getMetaData();
        int columnCount = metaData.getColumnCount();
        //获取结果集中字段类型、字段名称 放入列表中
        for (int index = 1; index <= columnCount; index++) {
            String columnName = metaData.getColumnLabel(index);
            int jdbcType = metaData.getColumnType(index);
            Class<?> columnType = TypeHandlerRegister.getJavaType(jdbcType);
            if (columnType == null) {
                throw new DarlingException("darling无法识别的jdbc类型:"+jdbcType);
            }
            columns.add(new Column(columnName, columnType));
        }

        return new Table(tableName, columns);
    }
}
